-- ======================================================================
-- Hell Lua Bus
-- 
-- Copyright 2012-2013Hell-Prototypes
--
-- http://www.hellprototypes.com/
--
-- This is free software, licensed under the terms of the GNU General
-- Public License as published by the Free Software Foundation.
-- ======================================================================
usb =require('libhlb')

module(..., package.seeall);
-- Define ----------------------------------------------------------------------
-- Serial data format control:
-- -- True: MSB first, false: LSB first 
DEFINE_DATA_MSB_FIRST = true 

-- SPI pin index define --------------------------------------------------------
SPI_MOSI_PIN = -1
SPI_MISO_PIN = -1
SPI_SCK_PIN  = -1
SPI_SS_PIN   = -1
-- -----------------------------------------------------------------------------
LSB_first_byte_mask = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}
MSB_first_byte_mask = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}

g_byte_mask = {}
-- -----------------------------------------------------------------------------
function ms_delay(ms)
	hlb.msdelay(ms)
end
function us_delay(us)
	hlb.usdelay(us)
end
-- -----------------------------------------------------------------------------
function init(mosi, miso, sck, ss)
	SPI_MOSI_PIN = mosi
	SPI_MISO_PIN = miso
	SPI_SCK_PIN  = sck
	SPI_SS_PIN   = ss
	
	local ret
	local init_io_data = 0
	local init_oe_data = LSB_first_byte_mask[SPI_MOSI_PIN+1] + LSB_first_byte_mask[SPI_SS_PIN+1] + LSB_first_byte_mask[SPI_SCK_PIN+1]

	ret = hlb.port_write(init_io_data)
	if ret < 0 then
		print("<SPI_MODE0> io_init : hlb_port_write ret = ", ret)
		return false
	end
	
	ret = hlb.port_oe(init_oe_data)
	if ret < 0 then
		print("<SPI_MODE0> io_init : hlb_port_oe ret = ", ret)
		return false
	end
	
	if DEFINE_DATA_MSB_FIRST then
    	g_byte_mask = MSB_first_byte_mask
    else
    	g_byte_mask = LSB_first_byte_mask
    end
end

function get_MISO()
	return hlb.get_bit(SPI_MISO_PIN)
end

function pin_set(pin)
	local ret = hlb.set_bit( pin )
	if ret < 0 then
		print("<SPI_MODE0> Pin" .. pin .." : hlb_set_bit ret = ", ret)
	end
end

function pin_reset( pin )
	local ret = hlb.clr_bit( pin )
	if ret < 0 then
		print("<SPI_MODE0> Pin" .. pin .." : hlb_clr_bit ret = ", ret)
	end
end
-- -----------------------------------------------------------------------------
function send_8bit(data)
	local data_8bit = bit32.band(data, 0xFF)
	--print(string.format("<SPI_MODE0> send_8bit: data_8bit = 0x%x", data_8bit))
	local ret_val = 0;

	for index = 1, 8 do
		if bit32.btest(data_8bit , g_byte_mask[index]) then
			pin_set(SPI_MOSI_PIN)
		else 
			pin_reset(SPI_MOSI_PIN)
		end
		--us_delay(10)
		
		if get_MISO() then
			ret_val = ret_val + g_byte_mask[index]
		end
		
		pin_set(SPI_SCK_PIN)
		--us_delay(10)
		pin_reset(SPI_SCK_PIN)
		
	end
	--print(string.format("<SPI_MODE0> send_8bit: ret_val = 0x%x", ret_val))
	return ret_val
end

function send_16bit(data)
	send_8bit(bit32.rshift(data, 8))
	return send_8bit(data)
end

function send_32bit(data)
	send_16bit(bit32.rshift(data, 16))
	return send_16bit(data)
end
-- -----------------------------------------------------------------------------
function device_open()
	local ret = hlb.usb_open()
	if ret < 0 then
		return false
	end
	
	return true
end

function device_close()
	local ret = hlb.usb_close()
	if ret < 0 then
		return false
	end
	
	return true
end